package com.company.hrmadmin.modules.interceptor;

import com.company.hrmadmin.common.constant.GlobalConstant;
import com.company.hrmadmin.common.util.CookieUtil;
import com.company.hrmadmin.common.util.HostHolder;
import com.company.hrmadmin.modules.domain.LoginToken;
import com.company.hrmadmin.modules.domain.User;
import com.company.hrmadmin.modules.mapper.UserMapper;
import com.company.hrmadmin.modules.service.LoginTokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * 登录Token的拦截器
 * 检查登录Token以及存储用户的一些信息
 *
 * @author Song, Wei
 * Date: 2022/3/21 10:59
 */
@Component
public class LoginTokenInterceptor implements HandlerInterceptor {

    @Resource
    private UserMapper userMapper;
    @Autowired
    private HostHolder hostHolder;
    @Autowired
    private LoginTokenService loginTokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 处理OPTIONS请求(预检请求)，具体看参阅“参考链接>>>http的协议的跨域cors 和 options请求的一些理解”
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "86400");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Content-Type", "text/html;charset=utf-8");
        if (request.getMethod().equals("OPTIONS")) {
            response.setStatus(HttpServletResponse.SC_OK);
            return false;
        }
        // 处理逻辑：主要是从 request 对象中将 Cookie 对象取出来，获得登录凭证
        String token = CookieUtil.getValue(request, GlobalConstant.TOKEN_NAME);
        token = token == null ? request.getHeader(GlobalConstant.TOKEN_NAME) : token;
        if (token != null) {
            // 表示存在登录凭证
            LoginToken loginToken = loginTokenService.getLoginToken(token);
            // 检查登录凭证是否失效
            if (loginToken != null && loginToken.getStatus() == 0 & loginToken.getExpiredTime().after(new Date())) {
                // 根据凭证查询用户
                User user = userMapper.selectById(loginToken.getUserId());
                // 在本次请求中持有用户，使用 ThreadLocal 存储用户
                hostHolder.setUser(user);
                // 将用户授权结果存入 SecurityContext 中，便于 Security 进行授权
//                Authentication authentication = new UsernamePasswordAuthenticationToken(
//                        user, user.getPassword(), userService.getAuthorities(user.getId())
//                );
//                SecurityContextHolder.setContext(new SecurityContextImpl(authentication));
            }
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 在视图渲染之后执行，此时已经可以将 ThreadLocal 中的对象清除
        hostHolder.removeUser();
        // 将 SecurityContextHolder 也同样进行清理
//        SecurityContextHolder.clearContext();
    }

}
